home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac-Source 1994 July
/
Mac-Source_July_1994.iso
/
C and C++
/
Entertainment
/
crabs.c
Wrap
Text File
|
1986-04-19
|
9KB
|
320 lines
/* ----------------- crabs -----------------
*
* Implementation of the crabs game for the
* Macintosh, written in Aztec C.
* See Scientific American, Sep 1985, p18-23.
*
* Author: Fons Rademakers, Nikhef-h/CERN
* Version: 29-oct-1985
* Revision:
*
*/
#asm
main
dc.w $6400 ;ctl-enable, need time and locked in mem.
dc.w 0 ;update as often as possible
dc.w $0001 ;don't react on any specific event
dc.w 0 ;no menu
dc.w open_-main ;open routine
dc.w nop_-main ;prime routine
dc.w control_-main ;control routine
dc.w nop_-main ;status routine
dc.w close_-main ;close routine
title_
dc.b 8
dc.b "Crabs "
ds 0 ;for alignment
public _Uend_,_Dorg_,_Cend_
save_
lea main+(_Uend_-_Dorg_)+(_Cend_-main),a4 ;set up globals
move.l a0,Pbp_ ;save pb pointer
move.l a1,Dp_ ;save DCE pointer
rts
restore_
move.l Pbp_,a0
rts
#endasm
#define _DRIVER
#define SMALL_MEM
#include <quickdraw.h>
#include <memory.h>
#undef SMALL_MEM
#include <event.h>
#include <pb.h>
#include <desk.h>
#define NULL (0L)
#define BASE1 512 /* Mac screen size in x direction */
#define BASE2 342 /* Mac screen size in y direction */
#define MAXVEL 8 /* max velocity of the crabs */
#define CRABS 10 /* # of crabs */
#define SP (*(struct storage **)Dp->dCtlStorage)
DCEPtr Dp;
ParmBlkPtr Pbp;
Rect wind_rect = {0, 0, 0, 0};
struct storage {
BitMap crabmap[4]; /* the 4 crab bitmaps */
GrafPtr crabport; /* the crabs grafport */
Pattern gray; /* backgr fill pattern */
short crabspace[4][16]; /* space for the 4 crab bitmaps */
short portspace[54]; /* space for the crabport */
short xvel[CRABS], yvel[CRABS]; /* the crabs velocity */
short newdest[CRABS][2], olddest[CRABS][2]; /* the crabs pos. */
short olddir[CRABS]; /* the direction the crab was going
*/
Boolean oldbackgr[CRABS]; /* flag to see if crab was on backgr
*/
};
open()
{
register WindowPtr wp;
register struct DCE *dp;
register struct storage *sp;
extern char title[];
struct windowpeek {
GrafPort port;
int windowKind;
};
short x, i, dir;
Rect destrect;
save();
dp = Dp;
if (dp->dCtlWindow == NULL) {
HLock(dp->dCtlStorage = NewHandle((long) sizeof(struct storage)));
sp = SP;
/* create an invisible window */
dp->dCtlWindow =
wp = NewWindow(NULL, &wind_rect, title, FALSE, plainDBox, -1L, FALSE,
NULL);
((struct windowpeek *)wp)->windowKind = dp->dCtlRefNum;
/* allocate space for new crabport */
&sp->crabport->device = sp->portspace;
OpenPort(sp->crabport);
/* set the 4 crab bitmaps */
for(i = 0; i < 4; i++){
sp->crabmap[i].bounds.top = 0;
sp->crabmap[i].bounds.left = 0;
sp->crabmap[i].bounds.bottom = 8;
sp->crabmap[i].bounds.right = 8;
sp->crabmap[i].rowBytes = 2; /* needs to be even (to fit on a word)
*/
sp->crabmap[i].baseAddr = &sp->crabspace[i][0];
}
StuffHex(sp->crabmap[0].baseAddr, "\P910008007E004200810081004200BD00");
StuffHex(sp->crabmap[1].baseAddr, "\PBD0042008100810042007E0010008900");
StuffHex(sp->crabmap[2].baseAddr, "\PB1004C0084008500860084004C00B100");
StuffHex(sp->crabmap[3].baseAddr, "\P8D00320021006100A100210032008D00");
/* gray pattern */
StuffHex(sp->gray, "\PAA55AA55AA55AA55");
/* set the start positions of the crabs and draw them */
x = 0;
dir = 1;
for (i = 0; i < CRABS; i++){
sp->newdest[i][0] = x;
sp->newdest[i][1] = 0;
x += BASE1/CRABS;
destrect.left = sp->newdest[i][0];
destrect.top = sp->newdest[i][1];
destrect.right = sp->newdest[i][0] + 8;
destrect.bottom = sp->newdest[i][1] + 8;
CopyBits(&sp->crabmap[dir], &sp->crabport->portBits,
&sp->crabmap[dir].bounds, &destrect,
srcCopy, NULL);
sp->olddir[i] = dir;
sp->oldbackgr[i] = FALSE;
sp->olddest[i][0] = sp->newdest[i][0];
sp->olddest[i][1] = sp->newdest[i][1];
}
/* set the background pattern to gray */
BackPat(sp->gray);
HUnlock(dp->dCtlStorage);
}
restore();
return(0);
}
close()
{
register struct DCE *dp;
save();
dp = Dp;
/* get rid of the allocated space for the window and crabs */
DisposeWindow(dp->dCtlWindow);
dp->dCtlWindow = NULL;
DisposHandle(dp->dCtlStorage);
restore();
return(0);
}
nop()
{
return(0);
}
control()
{
register struct DCE *dp;
register struct storage *sp;
short x, y, i, j, dir;
Rect grayrect, destrect;
Boolean backgr;
save();
dp = Dp;
HLock(dp->dCtlStorage);
sp = SP;
switch (Pbp->u.cp.csCode) {
case accRun: /* time to move the crabs */
SetPort(sp->crabport);
for (i = 0; i < CRABS; i++) {
if (!sp->oldbackgr[i]) {
/* if crab was not on bakcgr, determine complete
* new x and y velocities */
sp->xvel[i] = rand(-5, 5);
sp->yvel[i] = rand(-5, 5);
} else {
/* if crab was on backgr, increase or decrease the
* x and y velocities only slightly */
if (sp->xvel[i] >= MAXVEL)
sp->xvel[i] += rand(-1, 0);
else if (sp->xvel[i] <= -MAXVEL)
sp->xvel[i] += rand(0, 1);
else
sp->xvel[i] += rand(-1,1);
if (sp->yvel[i] >= MAXVEL)
sp->yvel[i] += rand(-1, 0);
else if (sp->yvel[i] <= -MAXVEL)
sp->yvel[i] += rand(0, 1);
else
sp->yvel[i] += rand(-1 ,1);
}
/* update the crab position */
sp->newdest[i][0] += sp->xvel[i];
sp->newdest[i][1] += sp->yvel[i];
/* make sure to remain within screen boundaries */
while ((sp->newdest[i][0] < 0) || (sp->newdest[i][0] > BASE1 - 8) ||
(sp->newdest[i][1] < 0) || (sp->newdest[i][1] > BASE2 - 8)) {
sp->newdest[i][0] -= sp->xvel[i];
sp->newdest[i][1] -= sp->yvel[i];
sp->xvel[i] = rand(-5, 5);
sp->yvel[i] = rand(-5, 5);
sp->newdest[i][0] += sp->xvel[i];
sp->newdest[i][1] += sp->yvel[i];
}
/* calculate new direction of crab */
if (abs(sp->yvel[i]) >= abs(sp->xvel[i]))
if (sp->yvel[i] <= 0)
dir = 0;
else
dir = 1;
else
if (sp->xvel[i] >= 0)
dir = 2;
else
dir = 3;
/* erase the crab from the previous position, by drawing
* it over with the gray background */
grayrect.left = sp->olddest[i][0];
grayrect.top = sp->olddest[i][1];
grayrect.right = sp->olddest[i][0] + 8;
grayrect.bottom = sp->olddest[i][1] + 8;
EraseRect(&grayrect);
/* determine if the new position does occupy a
* non gray site */
j = 0;
backgr = TRUE;
x = sp->newdest[i][0];
if (sp->xvel[i] > 0)
y = sp->newdest[i][1] + 7; /* scan only bottom line */
else /* of new crab position */
y = sp->newdest[i][1]; /* or only top line */
for (;x <= sp->newdest[i][0] + 7; x++)
if (GetPixel(x, y)) j++;
if (j != 4) backgr = FALSE;
sp->oldbackgr[i] = backgr;
if (!backgr) {
/* if the site is not gray, make it gray and redraw
* the crab in the previous position */
grayrect.left = sp->newdest[i][0];
grayrect.top = sp->newdest[i][1];
grayrect.right = sp->newdest[i][0] + 8;
grayrect.bottom = sp->newdest[i][1] + 8;
EraseRect(&grayrect);
destrect.left = sp->olddest[i][0];
destrect.top = sp->olddest[i][1];
destrect.right = sp->olddest[i][0] + 8;
destrect.bottom = sp->olddest[i][1] + 8;
dir = sp->olddir[i];
CopyBits(&sp->crabmap[dir], &sp->crabport->portBits,
&sp->crabmap[dir].bounds, &destrect,
srcCopy, NULL);
sp->newdest[i][0] = sp->olddest[i][0];
sp->newdest[i][1] = sp->olddest[i][1];
} else {
/* if the site is gray, draw the crab in the new
* position */
destrect.left = sp->newdest[i][0];
destrect.top = sp->newdest[i][1];
destrect.right = sp->newdest[i][0] + 8;
destrect.bottom = sp->newdest[i][1] + 8;
CopyBits(&sp->crabmap[dir], &sp->crabport->portBits,
&sp->crabmap[dir].bounds, &destrect,
srcCopy, NULL);
sp->olddest[i][0] = sp->newdest[i][0];
sp->olddest[i][1] = sp->newdest[i][1];
sp->olddir[i] = dir;
}
}
break; /* end case */
}
HUnlock(dp->dCtlStorage);
restore();
return(0);
}
/* Return random number uniformly distributed on [min,max].
* Note that Random() delivers a value on [-32768,32767]. */
rand(min, max)
int min, max;
{
float ran;
ran = (max - min + 1.0)*(float)abs(Random())/32768.0 + min;
return((ran < 0) ? --ran : ran);
}
/* Return absolute value of an integer */
abs(n)
int n;
{
return((n > 0) ? n : -n);
}